package org.example.mywebsite.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.mywebsite.entity.User;
import org.example.mywebsite.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequiredArgsConstructor
@Slf4j
@Tag(name = "登录接口")
@RequestMapping("/login")
public class LoginController {

    private final UserMapper userMapper;
    private final StringRedisTemplate redisTemplate;
    private final JavaMailSender mailSender;

    @Value("${sky.jwt.secret}")
    public String secret;

    @PostMapping
    @Operation(summary = "登录")
    public String login(@RequestParam String username,@RequestParam String password) {
        log.info("用户名：{}，密码：{}", username, password);
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            return null;
        }
        if (!user.getPassword().equals(password)) {
            return null;
        }
        int size = userMapper.selectList(null).size();
        try{
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", size);
            SecretKey secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
            String token = Jwts.builder()
                    .signWith(secretKey)
                    .claims( claims)
                    .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24))
                    .compact();
            return token;
        } catch (Exception e) {
            log.error("jwt操作失败:{}", e);
            throw new RuntimeException(e);
        }
    }

    @PostMapping("/register/captcha")
    @Operation(summary = "获取验证码")
    @Transactional
    public String captcha(@RequestParam String email){
        log.info("发送验证码:{}", email);
        String all = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder captcha = new StringBuilder();
        SimpleMailMessage message = new SimpleMailMessage();
        try{
            for(int i=0;i<6;i++){
                captcha.append(all.charAt((int)(Math.random()*all.length())));
            }

            message.setFrom("18776037834@163.com");
            message.setTo(email);
            message.setSubject("来自jun-666的验证码");
            message.setText("验证码："+captcha+"\n验证码有效期5分钟");
            mailSender.send(message);
        }catch (Exception e){
            log.error("发送验证码失败:{}", e);
            throw new RuntimeException(e);
        }
        try{
            ValueOperations<String, String> stringOps = redisTemplate.opsForValue();
            stringOps.set(email, captcha.toString(),5, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("redis操作失败:{}", e);
            throw new RuntimeException(e);
        }
        return "发送验证码成功";
    }

    @PostMapping("/register")
    @Operation(summary = "注册")
    public String register(@RequestBody User user){
        log.info("用户注册:{}", user);
        if(userMapper.selectOne(new QueryWrapper<User>().eq("username", user.getUsername()))!=null){
            return "用户名已存在";
        }
        if(userMapper.selectOne(new QueryWrapper<User>().eq("email", user.getEmail()))!=null){
            return "邮箱已存在";
        }
        String s = redisTemplate.opsForValue().get(user.getEmail());
        if (s == null){
            return "验证码已过期";
        }else{
            if (!s.equals(user.getCaptcha())){
                return "验证码错误";
            }
            int size = userMapper.selectList(null).size();
            user.setId(size+1);
            userMapper.insert(user);
        }

        return "注册成功";
    }
}
